#pragma once

#include <vector>
#include <cassert>

namespace simulation {
	template<size_t N>
	class BitSet {
	private:
		std::vector<char> _bits; //char也可以改成int，不过vector的长度要从N / 8 + 1变为N / 32 + 1
		size_t _cnt; //记录有多少个bit被set了

	public:
		BitSet()
			: _cnt(0)
		{
			_bits.resize((N >> 3) + 1); //N >> 3 == N / 2^3 == N / 8
		}

		~BitSet()
		{
			_cnt = 0;
		}

		void set(const size_t& pos)
		{
			assert(pos >= 0 && pos < N);

			size_t vecI = pos >> 3;
			size_t bitI = pos % 8;

			_bits[vecI] |= (1 << bitI);
			++_cnt;
		}

		void reset(const size_t& pos)
		{
			assert(pos >= 0 && pos < N);

			size_t vecI = pos >> 3;
			size_t bitI = pos % 8;

			_bits[vecI] &= (~(1 << bitI));
			--_cnt;
		}

		bool test(const size_t& pos) const
		{
			assert(pos >= 0 && pos < N);

			size_t vecI = pos >> 3;
			size_t bitI = pos % 8;

			return (bool)(_bits[vecI] & (1 << bitI));
		}

		size_t count() const
		{
			return _cnt;
		}

		size_t size() const
		{
			return N;
		}

		bool any() const
		{
			return _cnt != 0;
		}

		bool none() const
		{
			return _cnt == 0;
		}

		bool all() const
		{
			return _cnt == N;
		}
	};
}